/*
 * @ : Copyright (c) 2021 Phytium Information Technology, Inc.
 *
 * SPDX-License-Identifier: Apache-2.0.
 *
 * @Date: 2021-04-07 09:53:07
 * @LastEditTime: 2021-08-06 08:25:48
 * @Description:  This files is for assert function
 *
 * @Modify History:
 *  Ver   Who        Date         Changes
 * ----- ------     --------    --------------------------------------
 */

#ifndef Ft_assert_H
#define Ft_assert_H

#include "ft_types.h"
#include "ft_error_code.h"

#ifdef __cplusplus
extern "C"
{
#endif

#define FASSERT_NONE 0U
#define FASSERT_OCCURRED 1U
#define FT_ASSERT_APPEAR_BYTE 0xffU
#define FT_ASSERT_APPEAR FT_MAKE_ERRCODE(ErrModAssert, ErrBspGeneral, 1)

    extern u32 ft_assert_status;
    extern s32 ft_assert_wait;
    extern void FtAssert(char *file, s32 Line);

    typedef void (*FtAssertCallback)(char *File, s32 Line);

#define FT_ASSERTVOID(expression)                \
    {                                            \
        if (expression)                          \
        {                                        \
            ft_assert_status = FASSERT_NONE;     \
        }                                        \
        else                                     \
        {                                        \
            FtAssert(__FILE__, __LINE__);        \
            ft_assert_status = FASSERT_OCCURRED; \
            return;                              \
        }                                        \
    }

#define FT_ASSERTBOOL(expression)                \
    {                                            \
        if (expression)                          \
        {                                        \
            ft_assert_status = FASSERT_NONE;     \
        }                                        \
        else                                     \
        {                                        \
            FtAssert(__FILE__, __LINE__);        \
            ft_assert_status = FASSERT_OCCURRED; \
            return FALSE;                        \
        }                                        \
    }

/**
 * @name: Ft_assertZeroNum
 * @msg:  断言函数带返回值0
 * @param {*}
 * @return {*}
 */
#define FT_ASSERTZERONUM(expression)             \
    {                                            \
        if (expression)                          \
        {                                        \
            ft_assert_status = FASSERT_NONE;     \
        }                                        \
        else                                     \
        {                                        \
            FtAssert(__FILE__, __LINE__);        \
            ft_assert_status = FASSERT_OCCURRED; \
            return 0;                            \
        }                                        \
    }

/**
 * @name: FT_ASSERTNONVOID
 * @msg:  断言函数带返回值FT_ASSERT_APPEAR
 * @param {*}
 * @return {*}
 */
#define FT_ASSERTNONVOID(expression)             \
    {                                            \
        if (expression)                          \
        {                                        \
            ft_assert_status = FASSERT_NONE;     \
        }                                        \
        else                                     \
        {                                        \
            FtAssert(__FILE__, __LINE__);        \
            ft_assert_status = FASSERT_OCCURRED; \
            return FT_ASSERT_APPEAR;             \
        }                                        \
    }

#define FT_ASSERTBYTE(expression)                \
    {                                            \
        if (expression)                          \
        {                                        \
            ft_assert_status = FASSERT_NONE;     \
        }                                        \
        else                                     \
        {                                        \
            FtAssert(__FILE__, __LINE__);        \
            ft_assert_status = FASSERT_OCCURRED; \
            return FT_ASSERT_APPEAR_BYTE;        \
        }                                        \
    }

/**
 * @name: Ft_assertNoneReturn
 * @msg:  断言函数不返回
 * @param {*}
 * @return {*}
 */
#define FT_ASSERTNONERETURN(expression)          \
    {                                            \
        if (expression)                          \
        {                                        \
            ft_assert_status = FASSERT_NONE;     \
        }                                        \
        else                                     \
        {                                        \
            FtAssert(__FILE__, __LINE__);        \
            ft_assert_status = FASSERT_OCCURRED; \
            while (1)                            \
            {                                    \
            }                                    \
        }                                        \
    }

#define FT_ASSERTVOIDALWAYS()                \
    {                                        \
        FtAssert(__FILE__, __LINE__);        \
        ft_assert_status = FASSERT_OCCURRED; \
        return;                              \
    }

#define FT_ASSERTNONVOIDALWAYS()             \
    {                                        \
        FtAssert(__FILE__, __LINE__);        \
        ft_assert_status = FASSERT_OCCURRED; \
        return FT_ASSERT_APPEAR;             \
    }

    void FtAssertSetCb(FtAssertCallback routine);
#ifdef __cplusplus
}
#endif

#endif // !
